/*
 * @Description: 字段显隐规则配置-第一个Drawer
 * @Autor: gufuyan
 * @Date: 2021-11-15 10:30:41
 * @lastModifiedBy: gufuyan
 * @LastEditTime: 2021-12-03 16:40:43
 * @lastModifiedContent:
 */

import React, { useState, useEffect } from 'react';
import { Drawer, Button, Popconfirm, Tag } from 'antd';
import { PlusOutlined, QuestionCircleOutlined } from '@ant-design/icons';
import { useModel } from 'umi';
import { intl } from '../FormAttributes';
import AddFieldRule from './AddFieldRule';
import type { RulesType } from '@/models/drag';
import type { IShowFieldRuleProps, Option, FieldNameTree } from './data';
import { validationRules, dateFormula, dateDesc, dateType } from './constants';
import styles from './index.less';

const ShowFieldRule: React.FC<IShowFieldRuleProps> = (props) => {
  // 配置全局信息
  const drag = useModel('drag');
  // 显隐规则
  const rules: RulesType[] = [...drag.config.fieldShowRules];
  const [childrenDrawer, setChildrenDrawer] = useState(false);
  // 当前配置的显隐规则
  const [currentFieldRules, setCurrentFieldRules] = useState(rules);
  const [layoutField, setLayoutField] = useState<Record<string, FieldNameTree>>({});
  // 编辑类型和数据
  const [editType, setEditType] = useState<'add' | 'edit'>();
  const [editRule, setEditRule] = useState({});
  const [showFields, setShowFields] = useState(new Set());

  useEffect(() => {
    // 初始化设置layout数据
    const obj: Record<string, FieldNameTree> = {};
    drag.config?.contentItem?.forEach(
      (el: {
        name: string;
        id: string | number;
        title: string;
        field: string;
        props: { options: any };
        children: string | any[];
      }) => {
        if (!['placeBlock', 'splitLine'].includes(el.name)) {
          const data: any = {
            value: el.id,
            label: el.title,
            type: el.name,
            fieldName: el.field,
            fieldOptions: el.props?.options,
          };
          obj[el.id] = { ...data };
          if (el.children && el.children.length) {
            data.children = [];
            el.children[0].forEach(
              (childEl: {
                id: string;
                title: string;
                name: string;
                field: string;
                props: { options: any };
              }) => {
                const cData = {
                  value: childEl.id,
                  label: childEl.title,
                  type: childEl.name,
                  fieldName: childEl.field,
                  fieldOptions: childEl.props?.options,
                };
                obj[childEl.id] = { ...cData };
              },
            );
          }
        }
      },
    );
    setLayoutField(obj);
  }, [drag]);

  return (
    <Drawer
      title={intl('drag.exp.imp.title1')}
      key="drawer"
      placement="left"
      width={500}
      closable={false}
      visible={props.visible}
      style={{
        left: childrenDrawer ? 900 - 180 : 0,
      }}
      footer={
        <div className={styles.footer}>
          <Button
            className={styles.btn}
            onClick={() => {
              drag.fn.setFieldShowRule(currentFieldRules);
              props.handleClose();
            }}
          >
            {intl('drag.close')}
          </Button>
        </div>
      }
    >
      <p>
        {intl('drag.explicit.implicit.tip')}
        <a>{intl('drag.learn.more')}</a>
      </p>

      <Button
        type="primary"
        icon={<PlusOutlined />}
        onClick={() => {
          let newData: any = [];
          currentFieldRules.forEach((el) => newData.push(...el.fields));
          newData = new Set(newData);
          setShowFields(newData);
          setEditType('add');
          setEditRule({});
          setChildrenDrawer(true);
        }}
      >
        {intl('drag.explicit.implicit.btn')}
      </Button>

      {/* 规则列表 */}
      {Object.keys(layoutField).length > 0 &&
        currentFieldRules.map((item, idx) => {
          // 显隐规则
          const filterRule = item.filter?.cond?.map((el, index) => {
            let value = '';
            switch (el?.type) {
              case 'input':
                // 等于任意一个、不等于任意一个，采用标签显示
                value = ['in', 'nin'].includes(el.method || '')
                  ? el.value.map((inputval: Option) => (
                      <Tag key={inputval.value}>{inputval.label}</Tag>
                    ))
                  : el.value;
                break;
              case 'radio':
              case 'select':
                // 等于任意一个、不等于任意一个
                value = ['in', 'nin'].includes(el.method || '')
                  ? el.value?.map((radioval: Option) => (
                      <Tag key={radioval.value}>{radioval.label}</Tag>
                    ))
                  : el.value?.label || el.value;
                break;
              case 'checkbox':
                value = el.value;
                break;
              case 'datePicker':
              case 'dateRange':
                // 动态筛选
                if (el.method === 'formula') {
                  const type = dateFormula.filter((val) => val.value === el?.value?.formulaType)[0];
                  const flag = dateDesc.filter((val) => val.value === el?.value?.formulaFlag)[0];
                  const timeType = dateType.filter(
                    (val) => val.value === el?.value?.formulaTime,
                  )[0];
                  // 自定义
                  if (el?.value?.formulaType === 'custom') {
                    value = `${type.label}：${flag.label}${el?.value?.formulaNum}${timeType.label}`;
                  } else {
                    value = `${type.label}`;
                  }
                } else {
                  value = el?.value;
                }
                break;
              default:
                break;
            }

            return (
              <div key={el.field}>
                {index === 0 ? intl('drag.when') : intl('drag.and')}
                <span>「{layoutField[el.field]?.label}」</span>
                {validationRules[el.method].text}
                <span>「{value}」</span>时
              </div>
            );
          });

          // 显示字段
          const showField = (
            <div className={styles.show}>
              {intl('drag.show')}
              <span>
                「
                {item.fields
                  .map((el) => {
                    return layoutField[el].label;
                  })
                  .join()}
                」
              </span>
            </div>
          );

          return (
            <div key={item.tempId} className={styles.showItem}>
              {filterRule}
              {showField}
              <div className={styles.operate}>
                <div
                  className={styles.edit}
                  onClick={() => {
                    let newData: any = [];
                    currentFieldRules.forEach((el) => newData.push(...el.fields));
                    newData = new Set(newData);
                    setShowFields(newData);
                    setEditType('edit');
                    setEditRule(item);
                    setChildrenDrawer(true);
                  }}
                >
                  {intl('drag.edit')}
                </div>
                <Popconfirm
                  title="请确认是否删除该校验规则？"
                  icon={<QuestionCircleOutlined style={{ color: 'red' }} />}
                  onConfirm={() => {
                    const newRule = [...currentFieldRules];
                    newRule.splice(idx, 1);
                    setCurrentFieldRules(newRule);
                  }}
                >
                  <a className={styles.delete}>{intl('drag.delete')}</a>
                </Popconfirm>
              </div>
            </div>
          );
        })}

      {/* 添加显隐规则 */}
      <AddFieldRule
        visible={childrenDrawer}
        editType={editType}
        editRule={editRule}
        showFields={showFields}
        currentFieldRules={currentFieldRules}
        onClose={(rule) => {
          if (rule) setCurrentFieldRules(rule);
          setChildrenDrawer(false);
        }}
      />
    </Drawer>
  );
};

export default ShowFieldRule;
